﻿using Blm.PgsqlDriver.Helpers;
using Blm.Utils.Extensions;
using DocumentFormat.OpenXml.Drawing.ChartDrawing;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using VisionCloud.Core.Model.Ms;
using VisionCloud.Domain.DtoModel.Applet.RequestDto;
using VisionCloud.Domain.DtoModel.Ms;
using VisionCloud.Domain.Extension;
using VisionCloud.Domain.Repository.Interface.Ms;

namespace VisionCloud.Domain.Repository.Implement.Ms
{
    public class MsTaskPointsRepository : BaseRepository<TaskPoints>, IMsTaskPointsRepository
    {
        /// <summary>
        /// 根据任务Id和站点序号取站点对象
        /// </summary>
        /// <param name="taskId">任务Id</param>
        /// <param name="pointIndex">站点序号</param>
        /// <returns></returns>
        public async Task<TaskPoints> GetTaskPointsAsync(Guid taskId, int pointIndex)
        {
            return await (
                from h in Db.TaskPointss
                where h.TaskId == taskId && !h.IsDeleted && h.pintIndex == pointIndex
                select h).AsNoTracking().FirstOrDefaultAsync();
        }

        public async Task<List<TaskPoints>> GetTaskPoints(Guid taskId)
        {
            return await (
                from h in Db.TaskPointss
                where h.TaskId == taskId && !h.IsDeleted
                select h).AsNoTracking().OrderBy(x => x.pintIndex).ToListAsync();
        }

        public List<MsTaskPointIndexDto> GetFinishPoints(List<Guid> ids)
        {
            List<MsTaskPointIndexDto> list = new List<MsTaskPointIndexDto>();

            if (ids.IsEmpty())
                return list;

            var result = Db.TaskPointss.Where(p => ids.Contains(p.TaskId) && !p.IsDeleted && p.status == TaskPoints.PointStatus.测量完成).AsNoTracking().OrderBy(p => p.pintIndex).ToList();
            foreach (var item in result)
            {
                list.Add(new MsTaskPointIndexDto { Id = item.TaskId, Index = item.pintIndex });
            }

            return list;
        }

        public async Task<List<int>> GetFinishedPointIndex(QueryReportConditionDto condition)
        {
            var result = await (from p in Db.TaskPointss
                                join c in Db.CSMSTasks on p.TaskId equals c.TaskId
                                where c.ProjectId == condition.ProjectId && c.BuildingName == condition.Building && c.FloorName == condition.Floor && c.MeasureType == ((int)condition.MeasureType).ToString()
                                && !c.IsDeleted && p.status == TaskPoints.PointStatus.测量完成
                                select p.pintIndex).ToListAsync();
            return result;
        }

        public async ValueTask<bool> UpdatePointStatus(Guid taskId, int[] pointIndexs, TaskPoints.PointStatus status)
        {
            var list = await Db.TaskPointss.Where(p => p.TaskId == taskId && pointIndexs.Contains(p.pintIndex) && !p.IsDeleted).ToListAsync();
            foreach (var item in list)
            {
                item.status = status;
                item.LastUpdatedDate = DateTime.Now;
            }
            Db.TaskPointss.UpdateRange(list);
            var affrows = await Db.SaveChangesAsync();
            return affrows > 0;
        }

        public async ValueTask<List<PointMeasureResultInfo>> GetPointMeasureResult(Guid projectId, Guid taskId)
        {
            string sql = $@"SELECT a.""TaskId"",a.""pintIndex"" ""Index"",a.""HouseTypeName"",b.""tackpointjson"",b.""robotmeasuredesign"",c.""Name"" ""PointTypeName""
                        FROM ""TaskPoints"" a
                        inner join ""taskpointtable"" b on a.""TaskId"" = b.uuid and a.""pintIndex"" = b.""index""
                        inner join ""MsPointType"" c on a.""MsPointTypeId"" = c.""Id"" and c.""ProjectGuid"" = '{projectId}'
                        where a.""TaskId"" = '{taskId}' and a.""status"" = 3 and a.""IsDeleted"" = false and a.""HouseTypeName"" is not null
                        ORDER BY a.""pintIndex""";

            var list = await PgSqlHelper.QueryListAsync<PointMeasureResultInfo>(CommandType.Text, sql);

            return list;
        }

        public async Task<string> GetPointTypeByTaskId(Guid taskId, int pointIndex)
        {
            return await (from t in Db.MsTasks
                          join tp in Db.TaskPointss on t.TaskId equals tp.TaskId
                          join pt in Db.MsPointTypes on new { Id = tp.MsPointTypeId, t.ProjectId } equals new { pt.Id, ProjectId = pt.ProjectGuid }
                          where t.TaskId == taskId && tp.pintIndex == pointIndex
                          select pt.Name
                 ).FirstOrDefaultAsync();
        }
    }
}